<Table TItem="BindItem"
       IsPagination="true" PageItemsSource="@PageItemsSource"
       IsStriped="true" IsBordered="true"
       ShowToolbar="true" IsMultipleSelect="true" ShowExtendButtons="true"
       AddModalTitle="增加测试数据窗口" EditModalTitle="编辑测试数据窗口"
       OnQueryAsync="@OnEditQueryAsync"
       OnAddAsync="@OnAddAsync" OnSaveAsync="@OnSaveAsync" OnDeleteAsync="@OnDeleteAsync">
    <TableColumns>
        <TableColumn @bind-Field="@context.DateTime" Filterable="true" Sortable="true" />
        <TableColumn @bind-Field="@context.Name" Filterable="true" Sortable="true" />
        <TableColumn @bind-Field="@context.Address" Filterable="true" Sortable="true" />
        <TableColumn @bind-Field="@context.Count" Filterable="true" Sortable="true" />
    </TableColumns>
</Table>

@code {
    private static readonly object _objectLock = new object();

    /// <summary>
    /// 
    /// </summary>
    protected List<BindItem> EditItems { get; set; } = GenerateItems();

    /// <summary>
    /// 
    /// </summary>
    /// <param name="options"></param>
    /// <returns></returns>
    protected Task<QueryData<BindItem>> OnEditQueryAsync(QueryPageOptions options) => BindItemQueryAsync(EditItems, options);

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    protected Task<BindItem> OnAddAsync()
    {
        return Task.FromResult(new BindItem() { DateTime = DateTime.Now });
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    protected Task<bool> OnSaveAsync(BindItem item)
    {
        // 增加数据演示代码
        if (item.Id == 0)
        {
            lock (_objectLock)
            {
                item.Id = EditItems.Max(i => i.Id) + 1;
                EditItems.Add(item);
            }
        }
        else
        {
            var oldItem = EditItems.FirstOrDefault(i => i.Id == item.Id);
            oldItem.Name = item.Name;
            oldItem.Address = item.Address;
            oldItem.DateTime = item.DateTime;
            oldItem.Count = item.Count;
        }
        return Task.FromResult(true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="items"></param>
    /// <returns></returns>
    protected Task<bool> OnDeleteAsync(IEnumerable<BindItem> items)
    {
        items.ToList().ForEach(i => EditItems.Remove(i));
        return Task.FromResult(true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="items"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    protected Task<QueryData<BindItem>> BindItemQueryAsync(IEnumerable<BindItem> items, QueryPageOptions options)
    {
        //TODO: 此处代码后期精简
        if (!string.IsNullOrEmpty(SearchModel.Name)) items = items.Where(item => item.Name?.Contains(SearchModel.Name, StringComparison.OrdinalIgnoreCase) ?? false);
        if (!string.IsNullOrEmpty(SearchModel.Address)) items = items.Where(item => item.Address?.Contains(SearchModel.Address, StringComparison.OrdinalIgnoreCase) ?? false);
        if (!string.IsNullOrEmpty(options.SearchText)) items = items.Where(item => (item.Name?.Contains(options.SearchText) ?? false)
                || (item.Address?.Contains(options.SearchText) ?? false));

        // 过滤
        var isFiltered = false;
        if (options.Filters.Any())
        {
            items = items.Where(options.Filters.GetFilterFunc<BindItem>());

            // 通知内部已经过滤数据了
            isFiltered = true;
        }

        // 排序
        var isSorted = false;
        if (!string.IsNullOrEmpty(options.SortName))
        {
            // 外部未进行排序，内部自动进行排序处理
            var invoker = SortLambdaCache.GetOrAdd(typeof(BindItem), key => items.GetSortLambda().Compile());
            items = invoker(items, options.SortName, options.SortOrder);

            // 通知内部已经过滤数据了
            isSorted = true;
        }

        // 设置记录总数
        var total = items.Count();

        // 内存分页
        items = items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList();

        return Task.FromResult(new QueryData<BindItem>()
        {
            Items = items,
            TotalCount = total,
            IsSorted = isSorted,
            IsFiltered = isFiltered,
            IsSearch = !string.IsNullOrEmpty(SearchModel.Name) || !string.IsNullOrEmpty(SearchModel.Address)
        });
    }
}